package main

import (
	"fmt"
	"math/rand"
	"time"
)

/**
*  User: zhanbei
*  Date: 2025/10/27
*  Description: 星际穿越动画 - 星星从远处飞向屏幕的效果
 */

// Star 表示一个星星
type Star struct {
	x     float64
	y     float64
	z     float64 // 深度，用于计算大小和速度
	char  string
	speed float64
}

// RunTravel 星际穿越动画
func RunTravel() {
	rand.Seed(time.Now().UnixNano())

	width, height := getTerminalSize()

	// 隐藏光标
	hideCursor()
	defer showCursor()

	// 清屏
	clearScreen()

	// 显示标题
	moveCursor(width/2-15, 1)
	setColor(96) // 亮青色
	fmt.Print("✨ 星际穿越 - 按 Ctrl+C 退出 ✨")
	resetColor()

	// 创建星星
	stars := make([]*Star, 100)
	centerX := float64(width) / 2
	centerY := float64(height) / 2

	for i := range stars {
		stars[i] = &Star{
			x:     rand.Float64()*float64(width) - centerX,
			y:     rand.Float64()*float64(height) - centerY,
			z:     rand.Float64() * 2,
			char:  ".",
			speed: 0.05,
		}
	}

	// 设置超时
	done := make(chan bool)
	go func() {
		time.Sleep(30 * time.Second)
		done <- true
	}()

	// 动画循环
	ticker := time.NewTicker(50 * time.Millisecond)
	defer ticker.Stop()

loop:
	for {
		select {
		case <-done:
			break loop
		case <-ticker.C:
			// 清除旧的星星位置
			for row := 3; row < height; row++ {
				moveCursor(1, row)
				for col := 0; col < width; col++ {
					fmt.Print(" ")
				}
			}

			// 更新并绘制星星
			for _, star := range stars {
				// 更新深度
				star.z -= star.speed

				// 如果星星太近，重置到远处
				if star.z <= 0.1 {
					star.x = rand.Float64()*float64(width) - centerX
					star.y = rand.Float64()*float64(height) - centerY
					star.z = 2
				}

				// 计算屏幕坐标（透视投影）
				screenX := int(star.x/star.z + centerX)
				screenY := int(star.y/star.z + centerY)

				// 根据深度选择字符和颜色
				if star.z < 0.5 {
					star.char = "*"
					setColor(97) // 亮白色
				} else if star.z < 1.0 {
					star.char = "+"
					setColor(93) // 亮黄色
				} else {
					star.char = "."
					setColor(37) // 白色
				}

				// 绘制星星
				if screenX >= 1 && screenX <= width && screenY >= 3 && screenY <= height {
					moveCursor(screenX, screenY)
					fmt.Print(star.char)
				}
			}
			resetColor()
		}
	}

	// 清屏并显示结束信息
	clearScreen()
	moveCursor(width/2-10, height/2)
	setColor(96)
	fmt.Println("✨ 旅程结束！✨")
	resetColor()
	moveCursor(1, height)
	time.Sleep(1 * time.Second)
}
